package com.shide.common.util;

import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.util.*;

/**
 * 对象对比
 */
@Slf4j
public class ObjectComparator {
    // 公共自定义
    public static List<String> commonIgnoreFieldList = Arrays.asList("id", "isDeleted", "createdUserCode", "createdUserName",
            "updatedUserCode", "updatedUserName", "createdTime", "updatedTime");

    /**
     * 类对象对比
     *
     * @param previous 过去类
     * @param current  当前类
     * @return key: 字段名  value: [oldValue,newValue]
     */
    public static Map<String, String[]> compareObject(Object previous, Object current) {
        return compareObject(previous, current, null);
    }

    /**
     * 类对象对比
     *
     * @param previous                过去类
     * @param current                 当前类
     * @param customerIgnoreFieldList 要忽略对比的自定义字段列表
     * @return key: 字段名  value: [oldValue,newValue]
     */
    public static Map<String, String[]> compareObject(Object previous, Object current, List<String> customerIgnoreFieldList) {
        Map<String, String[]> differences = new HashMap<>();

        // 判断是否为相同的类
        if (previous.getClass() != current.getClass()) {
            throw new IllegalArgumentException("Objects must be of the same class.");
        }
        // 处理要忽略的字段
        if (customerIgnoreFieldList != null) {
            customerIgnoreFieldList.addAll(commonIgnoreFieldList);
        } else {
            customerIgnoreFieldList = commonIgnoreFieldList;
        }
        Set<String> ignoreFieldSet = new HashSet<>(customerIgnoreFieldList);

        // 获取所有的字段
        Field[] fields = previous.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true); // Allow access to private fields
            // 如果字段是需要忽略的，则跳过
            if (ignoreFieldSet.contains(field.getName())) {
                continue;
            }
            try {

                Object value1 = field.get(previous);
                Object value2 = field.get(current);

                // Compare field values
                if ((value1 != null && !value1.equals(value2)) || (value1 == null && value2 != null)) {
                    differences.put(field.getName(), new String[]{String.valueOf(value1), String.valueOf(value2)});
                }
            } catch (IllegalAccessException e) {
                log.error("e。。。。", e);
            }
        }

        return differences;
    }

}
